package ajakuulauku;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.MouseInputListener;

/**
 * Editor, for creating and editing maps
 * 
 * @author Valdar
 *
 */
public class Editor extends Engine implements MouseMotionListener, MouseInputListener, ActionListener {
	final static int normal = 0;
	final static int move = 1;
	final static int delete = 2;
	final static int add = 3;
	/**
	 * Background picture
	 */
	private BufferedImage backgroundImg = GUI.loadBufferedImage("images/Background-1.png");
	
	/**
	 * Object being dragged
	 */
	private GameObject draggedObj = null;
	
	/**
	 * Game objects for saving
	 */
	ArrayList<GameObject> editorObjects = new ArrayList<GameObject>();
	
	/**
	 * Right click menu
	 */
	JPopupMenu popup;
	
	/**
	 * Insert ball and insert hole menu items (for disabling)
	 */
	JMenuItem ballMenuItem, holeMenuItem;
	
	/**
	 * Current mode of editor(normal, move, delete)
	 */
	int editorMode = Editor.normal;
	
	JToggleButton currentButton = null;
	
	/**
	 * Initialize editor
	 */
	public Editor() {
		canv.init();
		canv.addMouseListener(this);
		canv.addMouseMotionListener(this);
		createToolBar();
	}
	
	private void createToolBar() {
		String[] objectNames = {"ball", "magnet", "hole", "pillar"};
		String[] buttonNames = {"Friction", "Save", "Quit", "Move", "Delete"};
		JPanel toolbar = new JPanel(new GridLayout(2, 1));
		JPanel menu = new JPanel(new GridLayout(buttonNames.length, 1));
		JPanel objects = new JPanel(new BorderLayout());
		objects.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
		
		for(String btnName : buttonNames) {
			JToggleButton btn = new JToggleButton(btnName);
			btn.setName(btnName.toLowerCase());
			btn.addActionListener(this);
			menu.add(btn);
		}
		
		toolbar.add(menu, BorderLayout.NORTH);
		
		JToolBar objectBar = new JToolBar(JToolBar.VERTICAL);
		objectBar.setFloatable(false);
		for(String objectName : objectNames) {
			GameObject obj = CurrentLevel.createGameObject(objectName);
			JToggleButton btn = new JToggleButton(obj.getEditorIcon());
			btn.setName("insert_"+objectName);
			btn.addActionListener(this);
			objectBar.add(btn);
		}
		JScrollPane scrollPane = new JScrollPane(objectBar, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
	            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		objects.add(scrollPane);
		toolbar.add(objects, BorderLayout.SOUTH);
		Dimension preferredSize = toolbar.getPreferredSize();
		preferredSize.height = 600;
		toolbar.setPreferredSize(preferredSize);
		JFrame parent = (JFrame)canv.getParent().getParent().getParent().getParent();
		parent.add(toolbar, BorderLayout.EAST);
		parent.pack();
	}

	/**
	 * Method executed every loop, draws game objects
	 */
	@Override
	void update() {
		canv.graphics.drawImage(backgroundImg, null, 0, 0);
		/*if(CurrentLevel.ball != null)
			CurrentLevel.ball.draw(canv.graphics);
		if(CurrentLevel.hole != null)
			CurrentLevel.hole.draw(canv.graphics);*/
		for (GameObject go : CurrentLevel.allObjects) {
			go.draw(canv.graphics);
		}
		if(draggedObj != null)
			draggedObj.draw(canv.graphics);
		canv.display();
	}

	/**
	 * Mouse event, when mouse button is released
	 * Shows right click menu and ends dragging
	 */
	@Override
	public void mouseReleased(MouseEvent e) {
		//If moving object cancel it
		if(e.isPopupTrigger()) {
			if(draggedObj != null) {
				draggedObj = null;
			}
		}else {
			if(draggedObj != null) {
				draggedObj.endDrag(e.getX(), e.getY());
				CurrentLevel.addObject(draggedObj.getClass().getSimpleName().toLowerCase(), draggedObj);
				draggedObj = null;
			}
		}
	}

	/**
	 * Event, for right click menu
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		if(currentButton != null)
			currentButton.setSelected(false);
		if(editorMode != Editor.normal) {
			if(draggedObj != null) {
				draggedObj.cancelDrag();
				draggedObj = null;
				editorMode = Editor.normal;
			}
		}
		//Get menu item
		JToggleButton source = (JToggleButton)e.getSource();
		String cmd = source.getName();
		if(cmd.contains("insert_")) {
			editorMode = Editor.add;
			cmd = cmd.substring(7);
			GameObject obj = CurrentLevel.createGameObject(cmd);
			obj.setX(Integer.MIN_VALUE);//Little hack so new object wouldnt appear in upper right corner
			draggedObj = obj;
		}else {
			//Shows dialog for setting friction
			if(cmd.contains("friction")) {
				String response = JOptionPane.showInputDialog(canv, "Modify friction", CurrentLevel.friction);
				try {
					CurrentLevel.friction = Double.parseDouble(response);
				}catch(Exception ex) {
					return;
				}
			}
			//Saves current level
			if(cmd.contains("save")) {
				for(GameObject obj : CurrentLevel.allObjects) {
					XMLElement element = obj.getXMLElement();
				}
				/*addObjects();
				//if (editorObjects.size() > 0) {
				String response = JOptionPane.showInputDialog(canv, "Enter a name");
				XMLMaster.Writer(response, editorObjects);
				//}*/
			}
			//Kills window and return to main menu
			if(cmd.contains("quit")) {
			   cleanUp();
			}
			
			if(cmd.contains("move")) {
				//source.setSelected(true);
			}
		}
		currentButton = source;
	}
	

	public void mouseMoved(MouseEvent e) {
		if(draggedObj != null) {
			draggedObj.drag(e.getX(), e.getY());
		}
	}
	
	public void mouseEntered(MouseEvent e) {
		if(draggedObj != null)
			draggedObj.startDrag(e.getX(), e.getY());
	}
	
	//Unused mouse events
	public void mouseExited(MouseEvent arg0) {}
	public void mouseDragged(MouseEvent e) {}
	public void mouseClicked(MouseEvent arg0) {}
	public void mousePressed(MouseEvent e) {}
	
	/**
	 * Prepares current level for saving
	 */
	private void addObjects () {
		ArrayList<GameObject> tmp = new ArrayList<GameObject>();
		
		for (int i = 0; i < CurrentLevel.allObjects.size(); i++) {
			tmp.add(CurrentLevel.allObjects.get(i));
		}
		/*for (int i = 0; i < CurrentLevel.magnets.size(); i++) {
			tmp.add(CurrentLevel.magnets.get(i));
		}
		for (int i = 0; i < CurrentLevel.pillars.size(); i++) {
			tmp.add(CurrentLevel.pillars.get(i));
		}
		for (int i = 0; i < CurrentLevel.balls.size(); i++) {
			tmp.add(CurrentLevel.balls.get(i));
		}
		for (int i = 0; i < CurrentLevel.holes.size(); i++) {
			tmp.add(CurrentLevel.holes.get(i));
		}*/
		
		editorObjects = tmp;
	}
}
